<?php

class Core_Request {
	
	protected $_params = array();

	protected static $_current = null;
	protected static $_initial = null;

	public $route;
	public $response;

	public function __construct($uri = null, $routes = array(), $base_url = '/') {
		if ($uri === null) {
			$uri = Request::detectUri($base_url);
		}

		$uri = trim($uri, '/');

		foreach($routes as $name => $route) {
			if ($params = $route->matches($uri)) {
				$this->uri     = $uri;
				$this->route   = $route;
				$this->_params = $params;

				if (!Request::$_initial)
					Request::$_initial = $this;

				return;
			}
		}

		throw new Exception("Route does not exist");
	}

	public function param($index, $value = null) {
		if ($value === null) 
			return array_key_exists($index, $this->_params) ? $this->_params[$index] : false;

		$this->_params[$index] = $value;

		return $this;
	}

	public function execute() {
		$previous          = Request::$_current;
		Request::$_current = $this;
		
		if (($callback = $this->route->callback()) !== false) {
			call_user_func_array($callback, array(&$this));
		}

		Request::$_current = $previous;

		return $this->response;
	}

	public static function current() {
		return Request::$_current;
	}

	public static function initial() {
		return Request::$_initial;
	}

	public static function detectUri($base_url) {
		if (!empty($_SERVER['PATH_INFO'])) {
			$uri = $_SERVER['PATH_INFO'];
		} else {
			if (isset($_SERVER['REQUEST_URI'])) {
				$uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

				$uri = rawurldecode($uri);
			} elseif (isset($_SERVER['PHP_SELF'])) {
				$uri = $_SERVER['PHP_SELF'];
			} elseif (isset($_SERVER['REDIRECT_URL'])) {
				$uri = $_SERVER['REDIRECT_URL'];
			} else {
				// 404
				throw new Exception("Route not found", 404);
			}

			// Get the path from the base URL, including the index file
	        $base_url = parse_url($base_url, PHP_URL_PATH);
	 
	        if (strpos($uri, $base_url) === 0) {
	            // Remove the base URL from the URI
	            $uri = (string)substr($uri, strlen($base_url));
	        }
	 
	        if (strpos($uri, 'index.php') === 0) {
	            // Remove the index file from the URI
	            $uri = (string)substr($uri, strlen('index.php'));
	        }
		}

		return $uri;
	}

}